package com.xndc.service.iec104;

import com.xndc.config.Iec104Config;
import com.xndc.netty.iec104.model.IEC104Frame;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * IEC 104连接管理器
 */
@Slf4j
@Component
public class Iec104ConnectionManager {
    
    /**
     * 设备通道映射(deviceId -> Channel)
     */
    private final Map<String, Channel> deviceChannels = new ConcurrentHashMap<>();
    
    /**
     * 公共地址到设备ID的映射(commonAddress -> deviceId)
     */
    private final Map<Integer, String> commonAddressToDeviceId = new ConcurrentHashMap<>();
    
    @Autowired
    private Iec104Config iec104Config;
    
    @PostConstruct
    public void init() {
        // 加载配置中的设备映射
        if (iec104Config.isEnabled() && iec104Config.getDevices() != null) {
            for (Iec104Config.DeviceMapping device : iec104Config.getDevices()) {
                commonAddressToDeviceId.put(device.getCommonAddress(), device.getDeviceId());
                log.info("加载IEC 104设备映射: 公共地址={}, 设备ID={}, 描述={}",
                        device.getCommonAddress(), device.getDeviceId(), device.getDescription());
            }
        }
    }
    
    /**
     * 注册设备连接
     */
    public void registerConnection(String deviceId, int commonAddress, Channel channel) {
        deviceChannels.put(deviceId, channel);
        commonAddressToDeviceId.put(commonAddress, deviceId);
        log.info("注册IEC 104设备连接: 公共地址={}, 设备ID={}", commonAddress, deviceId);
    }
    
    /**
     * 移除设备连接
     */
    public void removeConnection(String deviceId) {
        Channel channel = deviceChannels.remove(deviceId);
        if (channel != null) {
            log.info("移除IEC 104设备连接: 设备ID={}", deviceId);
        }
    }
    
    /**
     * 根据设备ID获取通道
     */
    public Channel getChannel(String deviceId) {
        return deviceChannels.get(deviceId);
    }
    
    /**
     * 根据公共地址获取设备ID
     */
    public String getDeviceIdByCommonAddress(int commonAddress) {
        return commonAddressToDeviceId.get(commonAddress);
    }
    
    /**
     * 发送命令到设备
     */
    public boolean sendCommand(String deviceId, IEC104Frame frame) {
        Channel channel = getChannel(deviceId);
        if (channel != null && channel.isActive()) {
            channel.writeAndFlush(frame);
            return true;
        }
        log.warn("发送命令失败，设备未连接: {}", deviceId);
        return false;
    }
    
    /**
     * 获取设备连接状态
     */
    public boolean isDeviceConnected(String deviceId) {
        Channel channel = getChannel(deviceId);
        return channel != null && channel.isActive();
    }
    
    /**
     * 获取已连接设备数量
     */
    public int getConnectedDeviceCount() {
        return (int) deviceChannels.values().stream()
                .filter(Channel::isActive)
                .count();
    }
} 